﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;


namespace ConwaysGameOfLife
{
    public partial class GamePage : PhoneApplicationPage
    {
        SpriteFont Font;

        UIElementRenderer elementRenderer;

        ContentManager contentManager;
        GameTimer timer;
        SpriteBatch spriteBatch;

        private Grid _grid;

        private Texture2D _blueSquare;
       private Texture2D _redSquare;

        private int _heightOfScreen;
        private int _widthOfScreen;

        private int _Cycles = 0;

        private int _RCellsLeft =20;
        private int _BCellsLeft = 20;

        private int _BTotalCells = -1;
        private int _RTotalCells = -1;

        public GamePage()
        {
            InitializeComponent();

            // Get the content manager from the application
            contentManager = (Application.Current as App).Content;

            // Create a timer for this page
            timer = new GameTimer();
            timer.UpdateInterval = TimeSpan.FromTicks(333333);
            timer.Update += OnUpdate;
            timer.Draw += OnDraw;


            
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // Set the sharing mode of the graphics device to turn on XNA rendering
            SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);

            _blueSquare = contentManager.Load<Texture2D>("block");
            _redSquare = contentManager.Load<Texture2D>("blockred");

            Font = contentManager.Load<SpriteFont>("Fonty");
            //get the width and height of screen
          _heightOfScreen = SharedGraphicsDeviceManager.DefaultBackBufferHeight-100;
          _widthOfScreen = SharedGraphicsDeviceManager.DefaultBackBufferWidth + 20;
         
          _grid = new Grid(new Vector2(_widthOfScreen / _blueSquare.Width, _heightOfScreen / _blueSquare.Height));

          if (null == elementRenderer)
          {
              elementRenderer = new UIElementRenderer(this, (int)_widthOfScreen, (int)_heightOfScreen+100);
          }

            // Start the timer
            timer.Start();

            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {


            // Stop the timer
            timer.Stop();
            
            // Set the sharing mode of the graphics device to turn off XNA rendering
            SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false);

            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Allows the page to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        private void OnUpdate(object sender, GameTimerEventArgs e)
        {

            TouchCollection touchCollection = TouchPanel.GetState();
            foreach (TouchLocation tl in touchCollection)
            {

                if (tl.State == TouchLocationState.Moved)
                {
                    if (Start.Content.ToString() == "Red")
                    {
                        if (_grid._GetStateOfCell((int)((tl.Position.X + 20) / _blueSquare.Width), (int)((tl.Position.Y + 20) / _blueSquare.Height)) == 0 && tl.Position.Y < _heightOfScreen-20 && _RCellsLeft > 0)
                        {
                            _RCellsLeft--;
                            _grid.SetStateOfCell((int)((tl.Position.X + 20) / _blueSquare.Width), (int)((tl.Position.Y + 20) / _blueSquare.Height), 2 );
                        }
                    }
                    else if (Start.Content.ToString() == "Blue")
                    {
                        if (_grid._GetStateOfCell((int)((tl.Position.X + 20) / _blueSquare.Width), (int)((tl.Position.Y + 20) / _blueSquare.Height)) == 0 && tl.Position.Y < _heightOfScreen - 20 && _BCellsLeft > 0)
                        {
                            _BCellsLeft--;
                            _grid.SetStateOfCell((int)((tl.Position.X + 20) / _blueSquare.Width), (int)((tl.Position.Y + 20) / _blueSquare.Height), 1);
                        }
                    }
                    
                }

            }
            if (_Cycles > 0)
            {
                _RTotalCells = 0;
                _BTotalCells = 0;
                List<List<int>> NewGrid = new List<List<int>>();
                for (int x = 0; x < _grid.GetWidth; x++)
                {
                    NewGrid.Add(new List<int>());
                    for (int y = 0; y < _grid.GetHeight; y++)
                    {
                        int StateOfCell = _grid._GetStateOfCell(x, y);
                        int RedNeighbors = 0;
                        int BluesNeighbors = 0;

                        if (StateOfCell == 1)
                        {
                            _RTotalCells++;
                        }
                        else if (StateOfCell == 2)
                        {
                            _BTotalCells++;
                        }
                      
                        if (_grid._GetStateOfCell(x - 1, y - 1) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x, y - 1) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x + 1, y - 1) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x - 1, y) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x + 1, y) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x - 1, y + 1) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x, y + 1) == 2)
                            RedNeighbors++;
                        if (_grid._GetStateOfCell(x + 1, y + 1) == 2)
                            RedNeighbors++;

                        //find blue neighbors
                        if (_grid._GetStateOfCell(x - 1, y - 1) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x, y - 1) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x + 1, y - 1) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x - 1, y) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x + 1, y) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x - 1, y + 1) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x, y + 1) == 1)
                            BluesNeighbors++;
                        if (_grid._GetStateOfCell(x + 1, y + 1) ==1)
                            BluesNeighbors++;

                        if (StateOfCell == 0)
                        {
                            if (RedNeighbors + BluesNeighbors == 3)
                            {
                                if (RedNeighbors > BluesNeighbors)
                                {
                                    NewGrid[x].Add(2);
                                }
                                else
                                {
                                    NewGrid[x].Add(1);
                                }
                            }
                            else
                            {
                                NewGrid[x].Add(0);
                            }
                        }
                        else
                        {
                            if (RedNeighbors + BluesNeighbors <= 1)
                            {
                                NewGrid[x].Add(0);
                            }
                            else if (RedNeighbors + BluesNeighbors >= 4)
                            {

                                NewGrid[x].Add(0);
                            }
                            else
                            {
                                if (RedNeighbors > BluesNeighbors)
                                {
                                    NewGrid[x].Add(2);
                                }
                                else
                                {
                                    NewGrid[x].Add(1);
                                }
                            }
                        }
                    }

                }

                _grid._GetGrid = NewGrid;
                _Cycles--;
                if (_Cycles == 0)
                {
                    Start.Content = "Red";
                }
            }
            //update the info on the bottom
            _updatePresentInformation();
        }

        /// <summary>
        /// Allows the page to draw itself.
        /// </summary>
        private void OnDraw(object sender, GameTimerEventArgs e)
        {
          
            elementRenderer.Render();

            SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.LightGray);
            spriteBatch.Begin();
            for (int x = 0; x < _grid.GetWidth; x++)
            {
                for (int y= 0;y < _grid.GetHeight; y++)
                {
                    if (_grid._GetStateOfCell(x, y) == 1)
                    {
                        spriteBatch.Draw(_blueSquare, new Vector2((x-1) * _blueSquare.Width, (y-1) * _blueSquare.Height), Color.White);
                    }
                    if (_grid._GetStateOfCell(x, y) == 2)
                    {
                        spriteBatch.Draw(_redSquare, new Vector2((x - 1) * _blueSquare.Width, (y - 1) * _blueSquare.Height), Color.White);
                    }
                }
            }
            spriteBatch.Draw(elementRenderer.Texture, Vector2.Zero, Color.White);
            if (_RTotalCells == 0)
            {
                spriteBatch.DrawString(Font, "Red WIN WIN", new Vector2((_widthOfScreen / 2) - (Font.MeasureString("Red WIN WIN").X / 2), (_heightOfScreen / 2)), Color.Red);
              
                    Start.Content = "Restart";
            }
            else if (_BTotalCells == 0)
            {
                spriteBatch.DrawString(Font, "Blue WIN WIN", new Vector2((_widthOfScreen / 2) - (Font.MeasureString("Blue WIN WIN").X / 2), (_heightOfScreen / 2)), Color.Blue);
                
                    Start.Content = "Restart";
            }
            spriteBatch.End();
            // TODO: Add your drawing code here
        }

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            if (Start.Content.ToString() == "Red" && _RCellsLeft == 0)
            {
                Start.Content = "Blue";
            
               
                
            }
            else if (Start.Content.ToString() == "Blue" && _BCellsLeft == 0)
            {
                Start.Content = "Wait...";
                _Cycles = 20;
                _RCellsLeft = 20;
                _BCellsLeft = 20;
            }

            if (Start.Content.ToString() == "Restart")
            {
                _grid.ClearGrid();
                  Start.Content = "Red";
                  _RTotalCells = -1;
                  _RCellsLeft = 20;
                  _BCellsLeft = 20;
                  _BTotalCells = -1;
            }
        }

        private void _updatePresentInformation()
        {
            RLeft.Text = ("Left:"+_RCellsLeft).ToString();
            BLeft.Text = ("Left:" + _BCellsLeft).ToString();

            RCell.Text = ("Cell:" + _RTotalCells).ToString();
            BCell.Text = ("Cell:" + _BTotalCells).ToString();
        }


        
    }
}